package com.freewater.library.catalogue.model;

import com.freewater.library.catalogue.model.event.BookDeletedEvent;
import com.freewater.library.catalogue.model.event.BookUpdatedEvent;
import com.freewater.library.common.domain.BaseAggregateRoot;
import com.freewater.library.common.domain.Nullable;
import lombok.Getter;
import org.apache.commons.lang3.Validate;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;

/**
 * 书
 */
@Getter
public class Book extends BaseAggregateRoot {
    /**
     * ISBN
     */
    private final String isbn;
    /**
     * 标题
     */
    private String title;
    /**
     * 副标题
     */
    private String subtitle;
    /**
     * 作者
     */
    private String author;
    /**
     * 出版社
     */
    private String publishingHouse;
    /**
     * 出版日期
     */
    private LocalDate publicationDate;
    /**
     * 封面图
     */
    private String cover;
    /**
     * 定价
     */
    private BigDecimal listPrice;
    /**
     * 页数
     */
    private Integer pageCount;
    /**
     * 装帧
     */
    private String bindingAndLayout;
    /**
     * 丛书
     */
    private String series;
    /**
     * 介绍/描述
     */
    private String description;

    @Override
    public Serializable getId() {
        return this.isbn;
    }

    public Book(String isbn, String title) {
        this(isbn,
                title,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null);
    }

    public Book(String isbn,
                String title,
                @Nullable String subtitle,
                @Nullable String author,
                @Nullable String publishingHouse,
                @Nullable LocalDate publicationDate,
                @Nullable String cover,
                @Nullable BigDecimal listPrice,
                @Nullable Integer pageCount,
                @Nullable String bindingAndLayout,
                @Nullable String series,
                @Nullable String description) {
        Validate.notBlank(isbn, "ISBN不能为空");
        Validate.notBlank(title, "标题不能为空");
        this.isbn = isbn;
        this.title = title;
        this.subtitle = subtitle;
        this.author = author;
        this.publishingHouse = publishingHouse;
        this.publicationDate = publicationDate;
        this.cover = cover;
        this.updateListPrice(listPrice);
        this.updatePageCount(pageCount);
        this.bindingAndLayout = bindingAndLayout;
        this.series = series;
        this.description = description;
    }

    /**
     * 更新书信息
     */
    public void update(String title,
                       @Nullable String subtitle,
                       @Nullable String author,
                       @Nullable String publishingHouse,
                       @Nullable LocalDate publicationDate,
                       @Nullable String cover,
                       @Nullable BigDecimal listPrice,
                       @Nullable Integer pageCount,
                       @Nullable String bindingAndLayout,
                       @Nullable String series,
                       @Nullable String description) {
        Validate.notBlank(title, "标题不能为空");
        this.title = title;
        this.subtitle = subtitle;
        this.author = author;
        this.publishingHouse = publishingHouse;
        this.publicationDate = publicationDate;
        this.cover = cover;
        this.updateListPrice(listPrice);
        this.updatePageCount(pageCount);
        this.bindingAndLayout = bindingAndLayout;
        this.series = series;
        this.description = description;
        this.raiseEvent(new BookUpdatedEvent(this.isbn));
    }

    /**
     * 书被删除
     */
    public void onDelete() {
        raiseEvent(new BookDeletedEvent(this.isbn));
    }

    private void updatePageCount(Integer pageCount) {
        this.pageCount = Math.max(0, pageCount == null ? 0 : pageCount);
    }

    private void updateListPrice(BigDecimal listPrice) {
        this.listPrice = listPrice == null ? BigDecimal.ZERO : listPrice;
    }
}
